package Demo5;

import java.util.PriorityQueue;

class TimerTask_2 implements Comparable<TimerTask_2>{
    private Runnable task;
    private long time;

    public TimerTask_2(Runnable task, long time) {
        this.task = task;
        this.time = time;
    }

    public long getTime() {
        return time;
    }

    public void run(){
        task.run();
    }

    @Override
    public int compareTo(TimerTask_2 o) {
        return (int)(this.time-o.time);
    }
}


class Timer_2{
   private PriorityQueue<TimerTask_2>queue=new PriorityQueue<>();
    Object lock=new Object();

    public void schedule(Runnable task,long delay){
        synchronized (lock){
            TimerTask_2 timerTask_2=new TimerTask_2(task,delay+System.currentTimeMillis());
            queue.offer(timerTask_2);
            lock.notify();
        }
    }

    public Timer_2() {
        Thread t=new Thread(()->{
            while(true){
                    try {
                        synchronized (lock){
                            while (queue.isEmpty()){
                                lock.wait();
                            }

                        TimerTask_2 task=queue.peek();
                        if(System.currentTimeMillis()<task.getTime()){
                            lock.wait(task.getTime()-System.currentTimeMillis());
                        }else {
                            task.run();
                            queue.poll();
                            lock.notify();
                        }
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
            }


        });
        t.start();
    }
}



public class Main18 {
    public static void main(String[] args) {
        Timer_2 timer_2=new Timer_2();

        timer_2.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        },3000);

        timer_2.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        },2000);

        timer_2.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        },1000);
        System.out.println("hello main");
    }
}
